package com.wing.product.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.constant.SecurityConstants;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.UniqueIdGeneratorUtil;
import com.wing.product.dao.WarehouseMaterialRequisitionRecordDetailDao;
import com.wing.product.dao.WarehouseOutboundOrderDao;
import com.wing.product.dao.WarehouseOutboundOrderDetailDao;
import com.wing.product.model.entity.WarehouseMaterialRequisitionRecordDetail;
import com.wing.product.model.entity.WarehouseOutboundOrder;
import com.wing.product.model.entity.WarehouseOutboundOrderDetail;
import com.wing.product.model.entity.WarehouseStorageOrder;
import com.wing.product.model.response.WarehouseOutboundOrderVO;
import com.wing.product.model.response.WarehouseProductInventoryVO;
import com.wing.product.model.response.WarehouseStorageOrderVO;
import com.wing.web.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WarehouseOutboundOrderServiceImpl extends ServiceImpl<WarehouseOutboundOrderDao, WarehouseOutboundOrder> implements WarehouseOutboundOrderService{

    @Autowired
    WarehouseOutboundOrderDetailDao warehouseOutboundOrderDetailDao;
    @Autowired
    WarehouseOutboundOrderDetailService warehouseOutboundOrderDetailService;
    @Autowired
    WarehouseMaterialRequisitionRecordDetailDao warehouseMaterialRequisitionRecordDetailDao;
    @Autowired
    WarehouseProductInventoryService warehouseProductInventoryService;

    @Override
    public Page<WarehouseOutboundOrderVO> pageList4app(Page page, Map<String, Object> params) {
        List<WarehouseOutboundOrderVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public WarehouseOutboundOrderVO selectOrderDetail(String id){
        //查询出库订单
        WarehouseOutboundOrderVO warehouseOutboundOrderVO = new WarehouseOutboundOrderVO();
        WarehouseOutboundOrder warehouseOutboundOrder = this.baseMapper.selectById(id);
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(WarehouseOutboundOrderVO.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(warehouseOutboundOrder, warehouseOutboundOrderVO, copyOptions);
        //查询出库订单明细
        LambdaQueryWrapper<WarehouseOutboundOrderDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WarehouseOutboundOrderDetail::getWarehouseOutboundOrderId,warehouseOutboundOrderVO.getId())
                .eq(WarehouseOutboundOrderDetail::getIsDeleted,0);
        List<WarehouseOutboundOrderDetail> warehouseOutboundOrderDetailList = warehouseOutboundOrderDetailDao.selectList(lambdaQueryWrapper);
        warehouseOutboundOrderVO.setWarehouseOutboundOrderDetailList(warehouseOutboundOrderDetailList);
       List<WarehouseProductInventoryVO> listProductInventoryVO = warehouseProductInventoryService.selectProductDetail(id);
        warehouseOutboundOrderVO.setWarehouseProductInventoryVOList(listProductInventoryVO);
        return warehouseOutboundOrderVO;
    }

    @Override
    public WarehouseOutboundOrderVO selectOrderDetailRecord(String id){
        //查询出库订单
        WarehouseOutboundOrderVO warehouseOutboundOrderVO = new WarehouseOutboundOrderVO();
        WarehouseOutboundOrder warehouseOutboundOrder = this.baseMapper.selectById(id);
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(WarehouseOutboundOrderVO.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(warehouseOutboundOrder, warehouseOutboundOrderVO, copyOptions);
        //查询出库订单明细
        LambdaQueryWrapper<WarehouseOutboundOrderDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WarehouseOutboundOrderDetail::getWarehouseOutboundOrderId,warehouseOutboundOrderVO.getId())
                .eq(WarehouseOutboundOrderDetail::getIsDeleted,0);
        List<WarehouseOutboundOrderDetail> warehouseOutboundOrderDetailList = warehouseOutboundOrderDetailDao.selectList(lambdaQueryWrapper);
        warehouseOutboundOrderVO.setWarehouseOutboundOrderDetailList(warehouseOutboundOrderDetailList);
        List<WarehouseProductInventoryVO> listProductInventoryVO = warehouseProductInventoryService.selectProductDetailOut(id);
        warehouseOutboundOrderVO.setWarehouseProductInventoryVOList(listProductInventoryVO);
        return warehouseOutboundOrderVO;
    }

    @Override
    @Transactional
    public JsonResult saveWarehouseOutboundOrder(WarehouseOutboundOrderVO warehouseOutboundOrderVO){

        if (ObjectUtil.isNotEmpty(warehouseOutboundOrderVO)){
            //添加出库记录
            WarehouseOutboundOrder warehouseOutboundOrder = new WarehouseOutboundOrder();
            CopyOptions copyOptions = CopyOptions.create()
                    .setEditable(WarehouseOutboundOrder.class)
                    .setIgnoreError(true)
                    .setIgnoreNullValue(true);
            BeanUtil.copyProperties(warehouseOutboundOrderVO, warehouseOutboundOrder, copyOptions);
            warehouseOutboundOrder.setWarehouseOutboundOrderCode(UniqueIdGeneratorUtil.generateUniqueId("CK", "yyyyMMddHHmmss", 1000, 9999));
            warehouseOutboundOrder.setStatus(1);
            if(JwtUtils.getClientId().equals(SecurityConstants.WAREHOUSE_CLIENT_ID)){
                warehouseOutboundOrder.setSources("2");
            }else {
                warehouseOutboundOrder.setSources("1");
            }
            if (!StringUtils.isEmpty(warehouseOutboundOrder.getBillLadingNumber())){
                LambdaQueryWrapper<WarehouseOutboundOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(WarehouseOutboundOrder::getBillLadingNumber,warehouseOutboundOrder.getBillLadingNumber())
                        .eq(WarehouseOutboundOrder::getIsDeleted,0);
                WarehouseOutboundOrder outboundOrder = this.baseMapper.selectOne(lambdaQueryWrapper);
                if (ObjectUtil.isNotEmpty(outboundOrder)){
                    return JsonResult.fail("此提单号已存在");
                }
            }
            this.baseMapper.insert(warehouseOutboundOrder);

            //添加出库明细
            if (CollectionUtils.isNotEmpty(warehouseOutboundOrderVO.getWarehouseOutboundOrderDetailList())){
                for (WarehouseOutboundOrderDetail ob : warehouseOutboundOrderVO.getWarehouseOutboundOrderDetailList()){
                    ob.setWarehouseOutboundOrderId(warehouseOutboundOrder.getId());
                    ob.setStatus(1);
                }
                warehouseOutboundOrderDetailService.saveBatch(warehouseOutboundOrderVO.getWarehouseOutboundOrderDetailList());
            }
            return JsonResult.success("添加成功");
        }else {
            return JsonResult.fail("添加失败");
        }
    }

    @Override
    public JsonResult<Map<Object, Object>> selectOutboundOrderTrend(){

        Map<Object,Object> orderMap = new HashMap<>();

        //出库订单
        LambdaQueryWrapper<WarehouseOutboundOrder> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper.eq(WarehouseOutboundOrder::getIsDeleted,0);
        List<WarehouseOutboundOrder> warehouseOutboundOrders = this.baseMapper.selectList(orderLambdaQueryWrapper);

        //领料出库
        LambdaQueryWrapper<WarehouseMaterialRequisitionRecordDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WarehouseMaterialRequisitionRecordDetail::getIsDeleted,0);
        List<WarehouseMaterialRequisitionRecordDetail> warehouseMaterialRequisitionRecordDetails = warehouseMaterialRequisitionRecordDetailDao.selectList(queryWrapper);

        LocalDate today = LocalDate.now();
        LocalDate sevenDaysAgo = today.minusDays(6);

        // 定义日期格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        Map<String, Long> dateCountMapOut = warehouseOutboundOrders.stream()
                .filter(inventory -> !inventory.getCreateTime().toLocalDate().isBefore(sevenDaysAgo)
                        && !inventory.getCreateTime().toLocalDate().isAfter(today))
                .collect(Collectors.groupingBy(
                        inventory -> inventory.getCreateTime().format(formatter), // 将LocalDateTime格式化为年月日
                        TreeMap::new,
                        Collectors.counting()
                ));

        Map<String, Long> materialRequisitionMap = warehouseMaterialRequisitionRecordDetails.stream()
                .filter(inventory -> !inventory.getCreateTime().toLocalDate().isBefore(sevenDaysAgo)
                        && !inventory.getCreateTime().toLocalDate().isAfter(today))
                .collect(Collectors.groupingBy(
                        inventory -> inventory.getCreateTime().format(formatter), // 将LocalDateTime格式化为年月日
                        TreeMap::new,
                        Collectors.counting()
                ));

        // 填充缺失的日期，确保前七天都有值
        for (LocalDate date = sevenDaysAgo; !date.isAfter(today); date = date.plusDays(1)) {
            String formattedDate = date.format(formatter);
            dateCountMapOut.putIfAbsent(formattedDate, 0L);
            materialRequisitionMap.putIfAbsent(formattedDate, 0L);
        }
        orderMap.put("out",dateCountMapOut);
        orderMap.put("materialRequisition",materialRequisitionMap);

        return JsonResult.success(orderMap);
    }

    @Override
    @Transactional
    public JsonResult updateOutboundOrder(String id, String status){
        LambdaUpdateWrapper<WarehouseOutboundOrder> lambdaUpdateWrapper =new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(WarehouseOutboundOrder::getId,id)
                .set(WarehouseOutboundOrder::getStatus,status);
        this.update(lambdaUpdateWrapper);
        return JsonResult.success("操作成功");
    }
}
